package cn.chenc.framework.jpa.service;

import cn.chenc.framework.core.text.Convert;
import cn.chenc.framework.core.util.AssertUtil;
import cn.chenc.framework.core.util.StringUtils;
import cn.chenc.framework.jpa.exception.RepositoryException;
import cn.chenc.framework.jpa.exception.ServiceException;
import cn.chenc.framework.jpa.model.PageInfo;
import cn.chenc.framework.jpa.repository.BaseRepository;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 　@description: TODO
 * 　@author secret
 * 　@date 2021/6/5 23:32
 *
 */
@Transactional
public class BaseServiceImpl <R extends BaseRepository<T,ID>,T,ID extends Serializable> implements BaseService<T, ID> {

    @PersistenceContext
    protected EntityManager entityManager;
    @Autowired
    R baseRepository;

    public BaseServiceImpl() {
    }


    public BaseRepository<T, ID> getBaseRepository(){
        return baseRepository;
    };

    @Override
    public T save(T t) throws ServiceException {
        return this.getBaseRepository().save(t);
    }

    @Modifying
    @Override
    public T update(T t) throws ServiceException {
        AssertUtil.notNull(t, "entity must not be null");

        try {
            return this.getBaseRepository().update(t);
        } catch (RepositoryException var3) {
            throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3);
        }
    }

    @Override
    public List<T> save(Iterable<T> entities) throws ServiceException {
        return this.getBaseRepository().saveAll(entities);
    }

    @Override
    @Transactional
    public T saveOrUpdate(ID id, T t) throws ServiceException {
        try {
            return this.getBaseRepository().saveOrUpdate(id, t);
        } catch (RepositoryException var4) {
            throw new ServiceException("Problem invoking method, Cause:" + var4.getMessage(), var4);
        }
    }

    @Override
    public T get(ID id) throws ServiceException {
        AssertUtil.notNull(id, "id must not be null");

        try {
            return this.getBaseRepository().get(id);
        } catch (RepositoryException var3) {
            throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3);
        }
    }

    @Override
    @Transactional
    public void delete(ID id) throws ServiceException {
        try {
            this.getBaseRepository().delete(id);
        } catch (RepositoryException var3) {
            throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3);
        }
    }

    @Override
    @Transactional
    public void delete(T t) throws ServiceException {
        AssertUtil.notNull(t, "The entity must not be null!");
        this.getBaseRepository().delete(t);
    }

    @Override
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void deleteAll(Iterable<T> entities) throws ServiceException {
        this.getBaseRepository().deleteAll(entities);
    }

    @Override
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void deleteBatchByIds(Collection<ID> ids) throws ServiceException {
        AssertUtil.notNull(ids, "id must not be null");
        Iterator var2 = ids.iterator();

        while(var2.hasNext()) {
            ID id = (ID) var2.next();
            this.getBaseRepository().deleteById(id);
        }

    }

    @Override
    public boolean exists(ID id) throws ServiceException {
        AssertUtil.notNull(id, "id must not be null");
        return this.getBaseRepository().existsById(id);
    }

    @Override
    public long count() throws ServiceException {
        return this.getBaseRepository().count();
    }

    @Override
    public List<T> findAll() throws ServiceException {
        return this.getBaseRepository().findAll();
    }

    @Override
    public List<T> findAll(T t) throws ServiceException {
        return this.getListByObject(t);
    }

    @Override
    public List<T> findAll(T t, Sort sort) throws ServiceException {
        Example<T> example = Example.of(t);
        return this.getBaseRepository().findAll(example, sort);
    }

    @Override
    public List<T> findAll(Sort sort) throws ServiceException {
        return this.getBaseRepository().findAll(sort);
    }

    @Override
    public List<T> findAll(Specification<T> specification) throws ServiceException {
        return this.getBaseRepository().findAll(specification);
    }

    @Override
    public Page<T> findAll(Pageable pageable) throws ServiceException {
        return this.getBaseRepository().findAll(pageable);
    }

    @Override
    public Page<T> findAll(T t, Pageable pageable) throws ServiceException {
        return this.getListByObject(t, pageable);
    }

    @Override
    public Page<T> findPage(Specification<T> specification, Pageable pageable) throws ServiceException {
        return this.getBaseRepository().findAll(specification, pageable);
    }

    @Override
    public T getOneByObject(T t) throws ServiceException {
        try {
            return this.getBaseRepository().getOneByObject(t);
        } catch (RepositoryException var3) {
            throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3);
        }
    }

    @Override
    public List<T> getListByObject(T t) throws ServiceException {
        try {
            return this.getBaseRepository().getListByObject(t);
        } catch (RepositoryException var3) {
            throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3);
        }
    }

    @Override
    public List<T> getListByObject(T t, Sort sort) throws ServiceException {
        try {
            return this.getBaseRepository().getListByObject(t, sort);
        } catch (RepositoryException var4) {
            throw new ServiceException("Problem invoking method, Cause:" + var4.getMessage(), var4);
        }
    }

    @Override
    public Page<T> getListByObject(T t, Pageable pageable) throws ServiceException {
        try {
            return this.getBaseRepository().getListByObject(t, pageable);
        } catch (RepositoryException var4) {
            throw new ServiceException("Problem invoking method, Cause:" + var4.getMessage(), var4);
        }
    }

    @Override
    public List<T> getListBySql(String sql) throws ServiceException {
        try {
            return this.getBaseRepository().getListBySql(sql);
        } catch (RepositoryException var3) {
            throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3);
        }
    }

    @Override
    public List<T> getListBySql(String sql, Class<T> clzss) throws ServiceException {
        try {
            return this.getBaseRepository().getListBySql(sql, clzss);
        } catch (RepositoryException var4) {
            throw new ServiceException("Problem invoking method, Cause:" + var4.getMessage(), var4);
        }
    }

    @Override
    public PageInfo getListBySql(String sql, PageInfo pageable) throws ServiceException {
        try {
            return this.getBaseRepository().getListBySql(sql, pageable);
        } catch (RepositoryException var4) {
            throw new ServiceException("Problem invoking method, Cause:" + var4.getMessage(), var4);
        }
    }

    @Override
    public List<Map<String, Object>> getListMapBySql(String sql) throws ServiceException {
        try {
            return this.getBaseRepository().getListMapBySql(sql);
        } catch (RepositoryException var3) {
            throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3);
        }
    }

    @Override
    public PageInfo getListMapBySql(String sql, PageInfo pageable) throws ServiceException {
        try {
            return this.getBaseRepository().getListMapBySql(sql, pageable);
        } catch (RepositoryException var4) {
            throw new ServiceException("Problem invoking method, Cause:" + var4.getMessage(), var4);
        }
    }

    @Override
    public Map<String, Object> getSingleMapBySql(String sql) throws ServiceException {
        try {
            return this.getBaseRepository().getSingleMapBySql(sql);
        } catch (RepositoryException var3) {
            throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3);
        }
    }

    @Override
    public int insertBySql(String sql) throws ServiceException {
        try {
            return this.getBaseRepository().insertBySql(sql);
        } catch (RepositoryException var3) {
            throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3);
        }
    }

    @Override
    public int updateBySql(String sql) throws ServiceException {
        try {
            return this.getBaseRepository().updateBySql(sql);
        } catch (RepositoryException var3) {
            throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3);
        }
    }

    @Override
    public int deleteBySql(String sql) throws ServiceException {
        try {
            return this.getBaseRepository().deleteBySql(sql);
        } catch (RepositoryException var3) {
            throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3);
        }
    }

    @Override
    public int executeBySql(String sql) throws ServiceException {
        try {
            return this.getBaseRepository().executeBySql(sql);
        } catch (RepositoryException var3) {
            throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3);
        }
    }

    @Override
    public int executeBySql(List<String> sqls) throws ServiceException {
        try {
            return this.getBaseRepository().executeBySql(sqls);
        } catch (RepositoryException var3) {
            throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3);
        }
    }

    @Override
    public int getCountBySql(String sql, Map<String, Object> searchMap) throws ServiceException {
        try {
            return this.getBaseRepository().getCountBySql(sql, searchMap);
        } catch (RepositoryException var4) {
            throw new ServiceException("Problem invoking method, Cause:" + var4.getMessage(), var4);
        }
    }

    @Override
    public Pageable getPageable(Map<String, Object> params) {
        Object pageNum = StringUtils.isEmpty((String) params.get("pageNum")) ? 1 : params.get("pageNum");
        Object pageSize = StringUtils.isEmpty((String) params.get("pageSize")) ? 10 : params.get("pageSize");
        return PageRequest.of(Convert.toInt(pageNum), Convert.toInt(pageSize));
    }

    @Override
    public PageInfo getPage(Map<String, Object> params) {
        Object pageNum = StringUtils.isEmpty((String) params.get("pageNum")) ? 1 : params.get("pageNum");
        Object pageSize = StringUtils.isEmpty((String) params.get("pageSize")) ? 10 : params.get("pageSize");
        return PageInfo.of(Convert.toInt(pageNum), Convert.toInt(pageSize));
    }

}
